﻿namespace Blaze.Framework.Pooling
{
    using UnityEngine.Assertions;

    /// <summary>
    /// 可重用对象的对象池实现。
    /// </summary>
    public class PoolableObjectPool<T> : ObjectPool<T> where T : class, IPoolable, new()
    {
        /// <summary>
        /// 从对象池中获取一个对象。
        /// </summary>
        /// <returns>可用的对象</returns>
        public override T Get()
        {
            T ret;
            if (AvailiableObjects.Count != 0)
            {
                ret = AvailiableObjects.Pop();
            }
            else
            {
                ret = Create();
            }
            OnGet(ret);
            return ret;
        }

        /// <summary>
        /// 将指定的对象回收到对象池。
        /// </summary>
        /// <param name="obj">对象</param>
        public override void Put(T obj)
        {
            Assert.IsFalse(AvailiableObjects.Contains(obj));
            OnPut(obj);
            AvailiableObjects.Push(obj);
        }

        /// <summary>
        /// 当需要创建一个新的对象时调用此方法。
        /// </summary>
        /// <returns></returns>
        protected override T Create()
        {
            return new T();
        }

        /// <summary>
        /// 当需要从对象池中获取对象时调用此方法。
        /// </summary>
        /// <param name="obj"></param>
        protected override void OnGet(T obj)
        {
            obj.OnGet();
        }

        /// <summary>
        /// 当需要回收指定对象时调用此方法。
        /// </summary>
        /// <param name="obj">需要回收的对象</param>
        protected override void OnPut(T obj)
        {
            obj.OnPut();
        }
    }
}